package com.koron.order.overhaul.service.impl;

import com.alibaba.fastjson.JSON;
import com.koron.common.core.util.CodeTools;
import com.koron.order.common.bean.po.OrderSignBean;
import com.koron.order.common.bean.vo.OrderExecuteVo;
import com.koron.order.common.service.OrderExecuteInfoService;
import com.koron.order.common.service.OrderInstructionService;
import com.koron.order.common.service.OrderSignService;
import com.koron.order.grade.service.OrderGradeService;
import com.koron.order.overhaul.bean.convertor.OverhaulOrderConvertor;
import com.koron.order.overhaul.bean.dto.Equipment;
import com.koron.order.overhaul.bean.entity.OverhaulMajorFormWorker;
import com.koron.order.overhaul.bean.entity.OverhaulOrderBean;
import com.koron.order.overhaul.bean.query.OverhaulOrderQuery;
import com.koron.order.overhaul.bean.vo.*;
import com.koron.order.overhaul.feign.EquipmentFeign;
import com.koron.order.overhaul.feign.PlanIssueFeign;
import com.koron.order.overhaul.mapper.OverhaulOrderMapper;
import com.koron.order.overhaul.service.*;
import com.koron.order.overhaul.utils.CommonUtils;
import com.koron.order.overhaul.utils.Constants;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.koron.ebs.mybatis.TaskAnnotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.groupingBy;

/**
 * @author twcao
 * @title: MobileOverhaulOrderServiceImpl
 * @projectName GDH_EAM_V2
 * @description: mobile-待修工单
 * @date 2021/11/1116:48
 */
@Slf4j
@Service
public class MobileOverhaulOrderServiceImpl implements MobileOverhaulOrderService {

    @Autowired
    private OverhaulOrderConvertor convertor;

    @Autowired
    private OrderExecuteInfoService executeInfoService;

    @Autowired
    private OrderInstructionService instructionService;

    @Autowired
    private OrderGradeService gradeService;

    @Autowired
    private EquipmentFeign equipmentFeign;

    @Autowired
    private OverhaulOrderService orderService;

    @Autowired
    private OverhaulOrderMajorFormService formService;

    @Autowired
    private OverhaulOrderItemParamsService paramsService;

    @Autowired
    private OverhaulMajorFormWorkerService workerService;

    @Autowired
    private OverhaulOrderItemService itemService;

    @Autowired
    private OverhaulOrderReadyService readyService;

    @Autowired
    private OrderSignService signService;

    @Autowired
    private PlanIssueFeign issueFeign;

    @Override
    @TaskAnnotation("queryById")
    public OverhaulOrderDetailVO queryById(SessionFactory factory, String orderId) {
        OverhaulOrderMapper mapper = factory.getMapper(OverhaulOrderMapper.class);
        OverhaulOrderDetailVO detailVo = mapper.queryById(orderId);
        Assert.notNull(detailVo, "工单Id=" + orderId + "不存在");
        detailVo.setDispatch(orderService.queryDispatchInfoByOrderId(factory, orderId));
        List<OrderExecuteVo> orderExecuteVos = executeInfoService.queryListByOrderId(factory, orderId);
        List<OrderExecuteVO> orderExecuteVOS = convertor.commonExecuteVosToExecuteVos(orderExecuteVos);
        Map<String, List<OrderExecuteVO>> executesMap = orderExecuteVOS.stream().collect(groupingBy(OrderExecuteVO::getMajorId));
        detailVo.getMajors().stream().forEach(major -> {
            major.setExecutes(executesMap.get(major.getId()));
            List<OverhaulOrderMajorFormVO> forms = major.getForms();
            forms.stream().forEach(form -> {
                List<OverhaulOrderItemVO> itemDTOs = form.getItemDTOs();
                itemDTOs.stream().forEach(item -> item.setSigns(orderService.getSignsByItemId(factory, item.getId())));
                form.setItemDTOs((CommonUtils.listToTree(itemDTOs, OverhaulOrderItemVO.class)));
            });
            major.setInstructions(instructionService.queryByBizId(factory, major.getId()));
        });
        detailVo.setGrades(gradeService.getGradeByOrderId(factory, orderId));
        if(StringUtils.equals(Constants.OrderSource.PLAN_ORDER, detailVo.getSourceId())) {
            Equipment equipment = CommonUtils.ok(equipmentFeign.queryById(detailVo.getEquipmentId()));
            detailVo.setTypeId(equipment.getTypeId());
        }
        return detailVo;
    }

    @Override
    @TaskAnnotation("queryList")
    public List<OverhaulOrderBean> queryList(SessionFactory factory, OverhaulOrderQuery query) {
        OverhaulOrderMapper mapper = factory.getMapper(OverhaulOrderMapper.class);
        List<OverhaulOrderBean> list = mapper.queryList(query);
        return list;
    }

    @Override
    @TaskAnnotation("executeSaveOrUpdate")
    public String executeSaveOrUpdate(SessionFactory factory, List<OverhaulOrderMajorFormVO> forms) {
        Assert.notEmpty(forms, "表单不能为空");
        String orderId = forms.get(0).getOverhaulId();
        Assert.hasText(orderId, "表单的工单id不能为空");
        formService.saveOrUpdate(factory, convertor.formVOsToBeans(forms));
        List<OverhaulOrderItemParamsVO> params = new ArrayList<>();
        List<OverhaulMajorFormWorker> workers = new ArrayList<>();
        List<OrderSignBean> signs = new ArrayList<>();
        forms.stream().forEach(form -> {
            form.setId(StringUtils.isBlank(form.getId()) ? CodeTools.getCode32() : form.getId());
            List<OverhaulMajorFormWorker> formWorkers = form.getFormWorkers();
            if(!CollectionUtils.isEmpty(formWorkers)) {
                formWorkers.stream().forEach(worker -> {
                    worker.setId(StringUtils.isBlank(worker.getId()) ? CodeTools.getCode32() : worker.getId());
                    worker.setFormId(form.getId());
                    worker.setOverhaulId(orderId);
                    worker.setMajorId(form.getMajorId());
                    workers.add(worker);
                });
            }
            // 嵌套列表，转成平铺列表
            List<OverhaulOrderItemVO> itemDTOs = (List<OverhaulOrderItemVO>) CommonUtils.tileToList(form.getItemDTOs());
            if(CollectionUtils.isEmpty(itemDTOs)) {
                return;
            }
            itemDTOs.stream().forEach(item -> {
                List<OverhaulOrderItemParamsVO> itemParams = item.getItemParams();
                if(CollectionUtils.isEmpty(itemParams)) {
                    return;
                }
                itemParams.stream().forEach(param -> {
                    param.setId(StringUtils.isNotBlank(param.getId()) ? param.getId() : CodeTools.getCode32());
                    param.setOverhaulId(orderId);
                    param.setItemId(item.getId());
                    params.add(param);
                });
            });
            if(!CollectionUtils.isEmpty(itemDTOs)) {
                signs.addAll(itemDTOs.stream().flatMap(item -> item.getSigns().stream()).collect(Collectors.toList()));
                itemService.saveOrUpdate(factory, convertor.itemVOsToBeans(itemDTOs));
            }
        });
        List<OverhaulOrderReadyVO> readies = forms.stream().flatMap(form -> form.getOverhaulReadies().stream()).collect(Collectors.toList());
        if(!CollectionUtils.isEmpty(readies)) {
            // 作业准备, pc端在草稿时填入，移动端只做修改，不做新增和删除
            readyService.saveOrUpdate(factory, convertor.readyVOsToBeans(readies));
        }
        if(!CollectionUtils.isEmpty(params)) {
            // 删除先前的参数, 移动端只做修改，不会新增和删除
            // paramsService.deleteByOrderId(factory, orderId);
            paramsService.saveOrUpdate(factory, convertor.paramVOsToBeans(params));
        }
        // 工作班成员
        if(!CollectionUtils.isEmpty(workers)) {
            workerService.deleteByOrderId(factory, orderId);
            workerService.saveOrUpdate(factory, workers);
        }
        // 签名
        if(!CollectionUtils.isEmpty(signs)) {
            signs.stream().forEach(row -> row.setId(StringUtils.isBlank(row.getId()) ? CodeTools.getCode32() : row.getId()));
            signService.insertBatch(factory, signs);
        }
        return orderId;
    }

    @Override
    @TaskAnnotation("updateStatus")
    public String updateStatus(SessionFactory factory, OverhaulOrderBean bean) {
        OverhaulOrderMapper mapper = factory.getMapper(OverhaulOrderMapper.class);
        Assert.hasText(bean.getId(), "工单id不能为空");
        OverhaulOrderBean db = mapper.getById(bean.getId());
        Assert.notNull(db, "工单不存在");
        db.setStatus(bean.getStatus());
        mapper.saveOrUpdate(db);
        if(Constants.OverhaulStatus.EXECUTE.equals(bean.getStatus())) {
            if(StringUtils.equals(db.getSourceId(), Constants.OrderSource.PLAN_ORDER)) {
                // 如果保存的工单状态是执行中且由计划生成，表明为提交到执行中，则通知生产计划，改变计划状态，开始执行
                log.info("工单调用生产计划，通知计划修改计划状态[开始执行], 参数code = {}", db.getCode());
                Object obj = CommonUtils.ok(issueFeign.issueExecute(db.getCode()));
                log.info("工单调用生产计划，通知计划修改计划状态[开始执行], response = {}", JSON.toJSONString(obj));
            }
            orderService.createGradeOrder(factory, bean.getId());
        }
        return bean.getId();
    }
}
